---
title: 概述
sidebar_position: -1
---




<RedSpan>领域驱动设计（DDD），在软件工程里，属于软件开发方法学的范畴</RedSpan>。它继承了面向对象和敏捷方法的精华，并提炼了一套更容易掌握的原则、模式和实践，特别适合复杂的企业应用的开发。


这些年，随着数字化转型的浪潮，我们为很多家大中型企业，在几十个项目里引入了 DDD，解决了很多实际的痛点和问题。


比如说，有的企业的业务很复杂，业务人员和开发人员总是很难把需求完全说清楚，直到写完代码，用户测试的时候，才知道开发人员的理解跑偏了。采用了 DDD 以后，就可以 <RedSpan>利用领域建模，把业务知识充分地严格化和可视化。这样，在分析设计阶段，就能对齐业务和开发的理解</RedSpan>。

还有一些系统的需求变化很快，开发很难跟上业务的节奏。有时为了能够在短期内应付变化，又会写出“打补丁”式的代码，给系统留下隐患。这种情况下，采用领域建模的方法，把 <RedSpan>领域知识抽象化，把相对稳定和相对变化的部分分开，并把变化的部分设计成可插拔、可配置的，就能开发出灵活、易扩展的系统</RedSpan>。

另外，还有一些项目希望采用微服务架构，但是缺乏拆分的依据，不知道怎么确定服务的粒度和边界。这时 <RedSpan>通过 DDD 的领域建模和限界上下文的划分，就可以给微服务的拆分提供坚实的基础</RedSpan>。


还有一种常见的问题，就是有些企业系统的架构和代码已经严重腐化了，希望通过重构来提高质量和可维护性。但是，应该往哪个方向重构呢？怎么在重构过程中降低风险，并且兼顾业务需求呢？

借助 DDD，就可以通过一套系统化的方法，<RedSpan>为系统建立目标模型和设计目标架构</RedSpan>。同时，再利用 DDD 的“柔性设计”，并且结合演进式架构和代码重构等等技术，就能很好地解决问题。

## DDD 说的是什么？
2003 年，Eric Evans 写了《领域驱动设计：软件核心复杂性应对之道》一书，正式提出了这种方法。领域驱动设计的英文是 Domain-Driven Design，所以简称 DDD。下面就是这本书的中英文封面：

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202411241159060.jpeg"/>

**DDD 是一种开发复杂软件的系统化的方法学和思想**

首先，到底什么是方法学？

假如你 Java 代码写得特别溜，那么可以说你掌握了面向对象的编程方法；假如你还很熟悉面向对象的设计原则，掌握很多设计模式，那可以说你懂面向对象的设计方法；假如你能为业务概念构建领域模型，那么你就懂了面向对象的分析方法。<RedSpan>面向对象的分析、设计、编码三种方法融会贯通，成为一个有机的整体，这个叫面向对象的方法学</RedSpan>。


刚才说，DDD 是系统化的方法学。那么什么是系统化呢？


咱们用数学举个例子。古代数学家祖冲之花了一辈子时间，用“割圆术”把圆周率算到小数点后 7 位，在当时已经是世界领先了。而现在的大学生，只要掌握了微积分，用一天的时间算出来的圆周率，就比祖冲之一辈子算出来的还准。

那么是不是可以说，现在随便一个大学生，智商都比祖冲之高呢？这可不见得。之所以我们算得比祖冲之准，是因为前辈们总结了微积分这套方法，我们站在了巨人的肩膀上才能做到。微积分，就是解决高等数学问题的系统化的方法。

所以，系统化方法的作用在于，提供了一套相对容易的步骤，能够使我们这些中等智商的人，也能做到原来高智商的人才能做到的事情，从而让你能够省出时间和脑力，来探索更复杂的问题。在软件开发领域，DDD 就是这样一套系统化的方法学。

不过，据说有人问过 Evans 本人：“DDD 是一种方法学吗？” Evans 说，DDD 不只是一种方法学，更重要的是背后的一套开发软件的思想和哲学。那么，DDD 中又蕴含着哪些思想和哲学呢？

归纳一下，大概有构建知识、分而治之、抓大放小、统一语言、抽象化、可视化、协作以及演进等等。凡是说到思想，都是一些大词儿，听起来都对，但是感觉好像没什么用，关键是不知道怎么落地。

**而 DDD 恰恰是通过总结了一套系统化的方法学，能够把这些大词落地**。
## 传统面向对象开发方法的问题

早期面向对象的成功，主要是在几个特定的领域，比如计算机语言、图形用户界面、办公自动化软件等等，但在企业应用方面还没有取得成功。所谓企业应用，包括像银行的贷款系统、保险公司的理赔系统、电信公司的计费系统等等。

那个时候的面向对象方法学还不能很好地应用于企业应用，大体上有以下几个原因。


第一个原因是，很多开发人员走了一条只重技术不重业务的弯路。重技术、不重业务的思想造成了业务和技术人员之间难以相互理解，技术人员难以真正满足业务需求，如果连需求的方向都搞错了，那么技术再纯熟也会南辕北辙。这样的弯路走了十几年，早期面向对象方法学的大好形势也就烟消云散了。

第二个原因是，围绕业务进行开发的方法本身就不好学。面向对象方法学主要是围绕领域建模开展的。领域建模这个东西，看老师傅做的时候好像挺简单，新手一上去，怎么做都不对。

第三个原因是，早期面向对象方法学主要考虑的是建模技术，很少考虑协作问题。

最后一个原因是难以适应变化。企业应用的需求往往变化频繁，很多变化根本无法预料。传统的面向对象方法学也很少讨论怎样应对变化的需求。

## DDD 的解决之道
可以说，DDD 正是为了解决上面这些问题而提出的。首先你从“领域驱动设计”这个名字就可以看出来。“领域”指的就是软件系统要解决的业务问题，也可以叫“业务领域”。用领域来驱动设计，就是说要从业务出发进行系统的设计。强调这个原则，就是希望把开发者从只重技术的弯路上拉回来。

要搞清业务，就要学会领域建模。前面也说了，这并不好学，那怎么办？DDD 采用了“模式”的方法。

我们都知道，老专家做事比新手做得好，说明专家心里一定有些新手不知道的东西。这些东西以前不容易讲清楚，后来有人把专家心里的这些高招都进行了系统化的梳理，每一条都是解决特定难题的通用的解决方案，这就是所谓“模式”。

计算机界最有名的是设计模式，后来又有分析模式、架构模式等等。读这些讲模式的书，就好像同时有好几个大师在给你讲课一样。通过学习模式，原来不容易掌握的东西就变得相对容易了。

Eric Evans 正是对面向对象方法学和敏捷软件开发方法进行了提炼，总结出了一套围绕领域建模进行软件开发的模式，一共有四十多个。这些模式成为《领域驱动设计》这本书的主体。

除了模式，书里还有一套相关的原则和实践。其中最基础的模式包括：模型驱动设计，实体、值对象等等。这些在后续的课程中，咱们都会讲清楚。

另一方面，领域驱动设计非常强调业务人员和技术人员要一起协作进行领域建模，在这个过程中提炼领域知识。和协作密切相关的模式有通用语言、模型驱动设计、限界上下文等等。实际上，这几个模式贯穿了整个 DDD。

此外，DDD 提出了所谓“柔性设计”的概念，使得模型和系统可以随着需求的变化而演进。什么意思呢？书里打了一个比方：这就好比一副新的皮手套，开始时整副手套都很僵硬；戴得久了，关节处就会自然变得柔软，而其他部分还是比较硬的。

同样，在软件设计中，也不是一开始就把所有地方都设计得很灵活，而是先进行“足够的”和“整洁的”设计。

随着业务变化，将变化频繁的部分重构得越来越灵活，而不常变化的部分则保持不变。也就是说，模型中的哪些部分需要设计得灵活，是自然演进形成的，这样就避免了“过度设计”。这个过程就是柔性设计。而这个重构的过程，也是不断加深领域知识理解的过程。

关于协作和演进，正是 DDD 的来源之一，敏捷软件开发所解决的重点问题。

## 总结
DDD 是一种开发复杂软件的系统化的方法学和思想。

DDD 建立在面向对象方法学和敏捷软件开发方法之上，一方面保留了面向对象的精华，另一方面又弥补了早期方法的不足。

DDD 从面向对象和敏捷中提炼出了一套原则、模式和实践，使面向对象方法学在企业应用中更加容易学习和掌握。

DDD 的核心是领域建模。领域模型是浓缩的领域知识。此外，DDD 还重视业务与技术人员的沟通，以及如何应对变化。

数字化时代为软件开发带来了新的挑战。如何实现业技融合，如何应对复杂多变的需求，如何防止架构和代码的腐化等问题，需要新的解决办法。而 DDD 正是顺应了时代的要求，才日益普及起来

